package com.springdoor.goods.service.impl;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import com.springdoor.common.constant.UserConstants;
import com.springdoor.common.core.domain.TreeSelect;
import com.springdoor.common.core.domain.entity.SprdGoodsAttr;
import com.springdoor.common.utils.StringUtils;
import com.springdoor.goods.domain.SprdGoodsTypeAttr;
import com.springdoor.goods.mapper.SprdGoodsTypeAttrMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.springdoor.goods.mapper.SprdGoodsTypeMapper;
import com.springdoor.common.core.domain.entity.SprdGoodsType;
import com.springdoor.goods.service.ISprdGoodsTypeService;

/**
 * 商品类型Service业务层处理
 *
 * @author llshs
 * @date 2024-04-30
 */
@Service
public class SprdGoodsTypeServiceImpl implements ISprdGoodsTypeService
{
    @Autowired
    private SprdGoodsTypeMapper typeMapper;

    @Autowired
    protected SprdGoodsTypeAttrMapper typeAttrMapper;

    /**
     * 查询商品类型
     *
     * @param gTypeId 商品类型主键
     * @return 商品类型
     */
    @Override
    public SprdGoodsType selectSprdGoodsTypeByGTypeId(Long gTypeId)
    {
        return typeMapper.selectSprdGoodsTypeByGTypeId(gTypeId);
    }

    /**
     * 查询商品类型列表
     *
     * @param sprdGoodsType 商品类型
     * @return 商品类型
     */
    @Override
    public List<SprdGoodsType> selectSprdGoodsTypeList(SprdGoodsType sprdGoodsType)
    {
        return typeMapper.selectSprdGoodsTypeList(sprdGoodsType);
    }

    /**
     * 新增商品类型
     *
     * @param sprdGoodsType 商品类型
     * @return 结果
     */
    @Override
    public int insertSprdGoodsType(SprdGoodsType sprdGoodsType)
    {
        typeMapper.insertSprdGoodsType(sprdGoodsType);
        return insertTypeAttr(sprdGoodsType);
    }

    /**
     * 修改商品类型
     *
     * @param sprdGoodsType 商品类型
     * @return 结果
     */
    @Override
    public int updateSprdGoodsType(SprdGoodsType sprdGoodsType)
    {
        typeAttrMapper.deleteTypeAttrByTypeId(sprdGoodsType.getgTypeId());
        insertTypeAttr(sprdGoodsType);
        return typeMapper.updateSprdGoodsType(sprdGoodsType);
    }

    @Override
    public int updateTypeStatus(SprdGoodsType sprdGoodsType) {
        return typeMapper.updateSprdGoodsType(sprdGoodsType);
    }

    /**
     * 删除商品类型信息
     *
     * @param gTypeId 商品类型主键
     * @return 结果
     */
    @Override
    public int deleteSprdGoodsTypeByGTypeId(Long gTypeId)
    {
        typeAttrMapper.deleteTypeAttrByTypeId(gTypeId);
        return typeMapper.deleteSprdGoodsTypeByGTypeId(gTypeId);
    }

    /*@Override
    public boolean checkGoodsTypeCodeUnique(SprdGoodsType goodsType) {
        Long typeId = StringUtils.isNull(goodsType.getgTypeId()) ? -1L : goodsType.getgTypeId();
        SprdGoodsType info = typeMapper.checkGoodsTypeCodeUnique(goodsType);
        if (StringUtils.isNotNull(info) && info.getgTypeId().longValue() != typeId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }*/

    @Override
    public boolean checkGoodsTypeNameUnique(SprdGoodsType goodsType) {
        Long typeId = StringUtils.isNull(goodsType.getgTypeId()) ? -1L : goodsType.getgTypeId();
        SprdGoodsType info = typeMapper.checkGoodsTypeNameUnique(goodsType);
        if (StringUtils.isNotNull(info) && info.getgTypeId().longValue() != typeId.longValue())
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public Integer findMaxOrderNum(Long typeId) {
        return typeMapper.findMaxOrderNum(typeId);
    }

    private int insertTypeAttr(SprdGoodsType goodsType) {
        int row = 0;
        List<SprdGoodsTypeAttr> list = new ArrayList<>();
        for (Long attrId: goodsType.getAttrIds()) {
            SprdGoodsTypeAttr attr = new SprdGoodsTypeAttr();
            attr.setTypeId(goodsType.getgTypeId());
            attr.setAttrId(attrId);
            list.add(attr);
        }
        if (!list.isEmpty()) {
            row = typeAttrMapper.batchTypeAttr(list);
        }
        return row;
    }

    @Override
    public List<SprdGoodsType> selectTypeAll() {
        return typeMapper.selectTypeAll();
    }

    @Override
    public List<TreeSelect> buildAttrTreeSelect(List<SprdGoodsType> list) {
        List<SprdGoodsType> trees = buildAttrTree(list);
        return trees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    private List<SprdGoodsType> buildAttrTree(List<SprdGoodsType> list) {
        List<SprdGoodsType> returnList = new ArrayList<SprdGoodsType>();
        List<Long> tempList = list.stream().map(SprdGoodsType::getgTypeId).collect(Collectors.toList());
        for (Iterator<SprdGoodsType> iterator = list.iterator(); iterator.hasNext();)
        {
            SprdGoodsType type = iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(type.getParentId()))
            {
                recursionFn(list, type);
                returnList.add(type);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = list;
        }
        return returnList;
    }

    private void recursionFn(List<SprdGoodsType> list, SprdGoodsType t) {
        // 得到子节点列表
        List<SprdGoodsType> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SprdGoodsType tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }

    private boolean hasChild(List<SprdGoodsType> list, SprdGoodsType t) {
        return getChildList(list, t).size() > 0;
    }

    private List<SprdGoodsType> getChildList(List<SprdGoodsType> list, SprdGoodsType t) {
        List<SprdGoodsType> tlist = new ArrayList<SprdGoodsType>();
        Iterator<SprdGoodsType> it = list.iterator();
        while (it.hasNext())
        {
            SprdGoodsType n = (SprdGoodsType) it.next();
            if (n.getParentId().longValue() == t.getgTypeId().longValue())
            {
                tlist.add(n);
            }
        }
        return tlist;
    }
}
